/**
 * 限制接口请求频次中间件
 * */
import { Injectable, NestMiddleware } from "@nestjs/common";
import { Request, Response } from "express";
import { StatusCode } from "src/utils/Mapping";
import { Vo } from "src/utils/Vo";

@Injectable()
export class RateLimitMiddleware implements NestMiddleware {
  // 存储每个 IP 地址的请求数
  private requests: Map<string, number> = new Map();
  // 允许的最大请求数
  private readonly rateLimit: number = 100;
  // 限制时间段，单位为毫秒（这里为1分钟）
  private readonly interval: number = 60 * 1000;

  use(req: Request, res: Response, next: () => void) {
    // 获取客户端IP地址
    const ip: string = req.ip;
    // 获取当前时间的时间戳
    const now: number = Date.now();
    // 判断该IP地址是否有过请求记录
    if (this.requests.has(ip)) {
      // 获取该IP地址的请求次数
      const requestsCount: number = this.requests.get(ip);
      // 判断该IP地址的请求次数是否超过了限制
      if (requestsCount > this.rateLimit) {
        return res.send(Vo.error("请求频率过快，请一分钟之后再试", null, {}, StatusCode.Often));
      } else {
        // 更新该IP地址的请求次数
        this.requests.set(ip, requestsCount + 1);
      }
    } else {
      // 如果该IP地址没有请求记录，则添加一条请求记录
      this.requests.set(ip, 1);
    }

    setTimeout(() => {
      // 在限制时间段结束后，从请求记录中删除该IP地址的请求记录
      this.requests.delete(ip);
    }, this.interval);

    // 调用下一个中间件或路由处理程序
    next();
  }
}
